from sys import exit
from PyMasterMindGraphic import*
from random import choice
from time import sleep

pygame.mixer.pre_init()
pygame.init()
screen = pygame.display.set_mode((776, 747), 0, 32)
pygame.display.set_caption("---00000---PYMASTER MIND---0000---")

sound_pine = pygame.mixer.Sound('sounds/pine.ogg')
sound_pine.set_volume(.1)
sound_win = pygame.mixer.Sound('sounds/win.ogg')
sound_win.set_volume(.6)
sound_try = pygame.mixer.Sound('sounds/try.ogg')
sound_try.set_volume(.3)
sound_lose = pygame.mixer.Sound('sounds/lose.wav')
sound_lose.set_volume(.1)
sound_button = pygame.mixer.Sound('sounds/button.wav')
sound_button.set_volume(.01)
sound_error = pygame.mixer.Sound('sounds/error.wav')
sound_error.set_volume(.1)

buttons = {}
buttons['single_player'] = Button('imagens/singleplayer.png', 'imagens/startgame.png', (30, 250))
buttons['how_to_play'] = Button('imagens/howtoplay.png', 'imagens/howtoplay_mouse.png', (30, 310))
buttons['thegame'] = Button('imagens/thegame.png', 'imagens/thegame_mouse.png', (30,370))
buttons['credits'] = Button('imagens/credits.png', 'imagens/credits_mouse.png', (30,430))
buttons['quit'] = Button('imagens/quit.png', 'imagens/quit_mouse.png', (30,490))

background = pygame.image.load('imagens/screen.png').convert()
mouse_cursor = pygame.image.load('imagens/mouse.png').convert_alpha()
background_play = pygame.image.load('imagens/screen_play.png').convert()
background_how = pygame.image.load('imagens/screen_how.png').convert()
background_thegame = pygame.image.load('imagens/screen_thegame.png').convert()
background_credits = pygame.image.load('imagens/screen_credits.png').convert()

GraphicPines = {}
GraphicPines['blue'] = GraphicPine('blue', 'imagens/pine_blue.png', (0,0))
GraphicPines['red'] = GraphicPine('red', 'imagens/pine_red.png', (0,0))
GraphicPines['green'] = GraphicPine('green', 'imagens/pine_green.png', (0,0))
GraphicPines['pink'] = GraphicPine('pink', 'imagens/pine_pink.png', (0,0))
GraphicPines['metal'] = GraphicPine('metal', 'imagens/pine_metal.png', (0,0))
GraphicPines['lilac'] = GraphicPine('lilac', 'imagens/pine_lilac.png', (0,0))
GraphicPines['colors'] = GraphicPine('colors', 'imagens/pine_colors.png', (0,0))
GraphicPines['orange'] = GraphicPine('orange', 'imagens/pine_orange.png', (0,0))

pygame.mouse.set_visible(False)
button_pressed = False
acknowledgments = ['Acknowledgments:', '  > Mister Dalton Serey', '  > Mister Jorge', '  > Mister Monitor Alex']

def print_display(msg, font, color, cord):
    impri = font.render(msg, True, color)
    screen.blit(impri, cord)
    return impri.get_size()

def how_to_play():
    button_how = Button('imagens/returntomenu_mouse.png', 'imagens/returntomenu.png', (522,0))    
    while True:
        screen.blit(background_how, (0,0))     
        button_how.render(screen)
        for event in pygame.event.get():   
            if event.type == MOUSEBUTTONDOWN:
                if is_over(button_how):
                    sound_button.play()                    
                    return
        screen.blit(mouse_cursor, pygame.mouse.get_pos())
        pygame.display.update()
        
def thegame():
    button_thegame = Button('imagens/returntomenu_mouse.png', 'imagens/returntomenu.png', (522,0))    
    while True:
        screen.blit(background_thegame, (0,0))     
        button_thegame.render(screen)
        for event in pygame.event.get():   
            if event.type == MOUSEBUTTONDOWN:
                if is_over(button_thegame):
                    sound_button.play()                    
                    return    
        screen.blit(mouse_cursor, pygame.mouse.get_pos())
        pygame.display.update()
        
def credits():
    button_thegame = Button('imagens/returntomenu_mouse.png', 'imagens/returntomenu.png', (522,0))
    font = pygame.font.SysFont('couriernew', 30)      
    while True:
        screen.blit(background_credits, (0,0))     
        button_thegame.render(screen)
        for n in xrange(len(acknowledgments)):
            print_display(acknowledgments[-n-1], font, (255,0,0), (150, 500 - 500 * (n+1)/12))
        for event in pygame.event.get():   
            if event.type == MOUSEBUTTONDOWN:
                if is_over(button_thegame):
                    sound_button.play()                    
                    return    
        screen.blit(mouse_cursor, pygame.mouse.get_pos())
        pygame.display.update()

def find_none(list_blocks):
    for block in list_blocks:   
        for i in xrange(len(block)):
            if block.get_pine(i) == None:
                return block, i
            
def instatiation(cord):
    block = GraphicBlock(5, 'imagens/block.png', cord)
    block_choice1 = GraphicBlock(4, 'imagens/block_choice.png', (cord[0] + 20, cord[1] + 50))
    block_choice2 = GraphicBlock(4, 'imagens/block_choice.png', (cord[0] + 20, cord[1] + 90))    
    for pine in GraphicPines.values():
        if not block_choice1.add_pine(pine, GraphicPines.values().index(pine)):
            block_choice2.add_pine(pine, GraphicPines.values().index(pine)-4)
    return block, block_choice1, block_choice2

def generate_password(size):
    password = GraphicBlock(size, 'imagens/block.png', (300, 700))
    GraphicPines_copy = GraphicPines.keys()    
    for position in xrange(size):
        pine = choice(GraphicPines_copy)
        GraphicPines_copy.pop(GraphicPines_copy.index(pine))
        password.add_pine(GraphicPine(pine, 'imagens/pine_%s.png'% pine), position)
    return password

def finished_win(block, password):
    return block == password

def finished_lose(list_blocks):
    return len(list_blocks) == 10
    
def play(size):

    password = generate_password(size)
    block, block_choice1, block_choice2 = instatiation((200, 140))
    
    button_pressed = None
    GraphicPine_mouse = None
    list_blocks = []
    buttons_play = {}
    buttons_play['try'] = Button('imagens/try.png', 'imagens/try_mouse.png', (block.cord[0] + 320, block.cord[1]))
    buttons_play['returntomenu'] = Button('imagens/returntomenu.png', 'imagens/returntomenu_mouse.png', (0,0))
    
    font = pygame.font.SysFont('monotypecorsiva', 35, True)
    count_sound = 0
        
    while True:
        
        screen.blit(background_play, (0,0))
        screen.blit(pygame.image.load('imagens/hints.png').convert_alpha(), (520, 70))
        num = 1
        for block_old, block_result in list_blocks:    
            print_display(str(num), font, (50,255,0), (block_old.cord[0] - 120, block_old.cord[1]))
            block_old.render(10, 'imagens/none.png', screen)
            block_result.render(5, 'imagens/result_none.png', screen)
            num += 1
            
        if finished_lose(list_blocks):
            print_display('You Lose!!', font, (50,255,0), (240, 80))
            print_display('Password:', font, (50,255,0), (100, 700))
            password.render(10, 'imagens/none.png', screen)
            if count_sound == 0:
               sleep(0.3) 
               sound_lose.play()
               count_sound +=1 
        elif finished_win(block, password) and not buttons_play.has_key('try'):
            print_display('You Win!!', font, (50,255,0), (240, 80))
            block.render(10, 'imagens/none.png', screen)
            if count_sound == 0:
                sleep(0.3)
                sound_win.play()
                count_sound +=1            
        else:
            block_choice1.render(10, 'imagens/none.png', screen)
            block_choice2.render(10, 'imagens/none.png', screen)
            block.render(10, 'imagens/none.png', screen)   
        
        for button in buttons_play.values():
            button.render(screen)    
            
        for event in pygame.event.get():    
            if event.type == MOUSEBUTTONDOWN: 
                for i in xrange(5):
                    if block.get_pine(i) != None and is_over(block.get_pine(i)):
                        block_choice, position = find_none([block_choice1, block_choice2])
                        block_choice.add_pine(block.get_pine(i), position)
                        block.remove_pine(i)
                    try:
                        if block_choice1.get_pine(i) != None and is_over(block_choice1.get_pine(i)):
                            GraphicPine_mouse = block_choice1.get_pine(i)
                            block_choice1.remove_pine(i)                            
                        elif block_choice2.get_pine(i) != None and is_over(block_choice2.get_pine(i)):
                            GraphicPine_mouse = block_choice2.get_pine(i)
                            block_choice2.remove_pine(i)
                    except 'InvalidPosition':
                        pass   
                for button_name, button in buttons_play.iteritems():
                    if is_over(button):
                        if button_name != 'try':
                            sound_button.play()
                        elif block.contains(None):
                            sound_error.play()
                        else:
                            sound_try.play()
                        button_pressed = button_name                  
                        break
            elif event.type == MOUSEBUTTONUP:  
                if GraphicPine_mouse != None:
                    for i in xrange(5):
                        x, y = block.cord
                        cord = (10 + x + (pygame.image.load('imagens/none.png').convert_alpha().get_size()[0] + 10) * i), y
                        if is_over(GraphicPine(None,'imagens/none.png', cord)):
                            over = True
                            sound_pine.play()
                            if not block.add_pine(GraphicPine_mouse, i):
                                block_choice, position = find_none([block_choice1, block_choice2])
                                block_choice.add_pine(GraphicPine_mouse, position)
                            break
                        over = False        
                    if not over:
                        block_choice, position = find_none([block_choice1, block_choice2])
                        block_choice.add_pine(GraphicPine_mouse, position)                        
                    GraphicPine_mouse = None
                   
        if button_pressed == 'try':
            if not block.contains(None) and not (finished_win(block, password) or finished_lose(list_blocks)):
                result_block = block.result_block(password)
                list_blocks.append((block.copy('imagens/block.png'), result_block.copy('imagens/block_result.png')))
                block, block_choice1, block_choice2 = instatiation((block.cord[0], block.cord[1]+50))
                buttons_play['try'].cord = (buttons_play['try'].cord[0], buttons_play['try'].cord[1] + 50)
            button_pressed = None
            if finished_win(password, block) or finished_lose(list_blocks):
                del buttons_play['try'] 
                             
        elif button_pressed == 'returntomenu':
            return      
        if GraphicPine_mouse != None:
            x, y = pygame.mouse.get_pos()
            w, h = GraphicPine_mouse.image.get_size()
            screen.blit(GraphicPine_mouse.image, (x - w/2, y - h/2))
        screen.blit(mouse_cursor, pygame.mouse.get_pos())
        pygame.display.update()
        
        
while True:
    
    screen.blit(background, (0,0))
    for button in buttons.values():
        button.render(screen)
    
    for event in pygame.event.get():                       
        if event.type == QUIT:
                exit()    
        if event.type == MOUSEBUTTONDOWN:   
            for button_name, button in buttons.iteritems():
                if is_over(button):
                    sound_button.play()
                    button_pressed = button_name                    
                    break
                
    if button_pressed is not None:
        if button_pressed == 'single_player':
            play(5)
        elif button_pressed == 'credits':
            credits()
        elif button_pressed == 'how_to_play':
           how_to_play()
        elif button_pressed == 'thegame':
            thegame()
        elif button_pressed == 'quit':
            exit()
    button_pressed = None
    screen.blit(mouse_cursor, pygame.mouse.get_pos())                          
    pygame.display.update()